home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 June (DVD) / DPPRO0605DVD.iso / Install / program files / Borland / BDS / 3.0 / Demos / Delphi.Net / CLR / MapQuest / PetrVones.Utils.SoapTrace.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2004-10-22  |  4.5 KB  |  179 lines

  1. unit PetrVones.Utils.SoapTrace;
  2.  
  3. // Reference:
  4. // http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemWebServicesProtocolsSoapExtensionClassTopic.asp
  5.  
  6. // Usage:
  7. // Add [TraceExtensionAttribute] to each method you'd like to monitor in code generated by WSDL importer
  8.  
  9. interface
  10.  
  11. uses
  12.   System.Xml, System.Web.Services, System.Web.Services.Protocols, System.IO;
  13.  
  14. type
  15.   TSoapMessageEvent = procedure (Sender: TObject; const Xml: string) of object;
  16.  
  17.   TSoapMonitor = class(TObject)
  18.   private
  19.     FOnRequest: TSoapMessageEvent;
  20.     FOnResponse: TSoapMessageEvent;
  21.   protected
  22.     procedure DoRequest(const Xml: string);
  23.     procedure DoResponse(const Xml: string);
  24.   public
  25.     class function FormatXmlData(const Xml: string): string; static;
  26.     property OnRequest: TSoapMessageEvent add FOnRequest remove FOnRequest;
  27.     property OnResponse: TSoapMessageEvent add FOnResponse remove FOnResponse;
  28.   end;
  29.  
  30.   [AttributeUsage(AttributeTargets.Method)]
  31.   TraceExtensionAttribute = class(SoapExtensionAttribute)
  32.   strict private
  33.     FPriority: Integer;
  34.   public
  35.     function get_ExtensionType: System.Type; override;
  36.     function get_Priority: Integer; override;
  37.     procedure set_Priority(value: Integer); override;
  38.   end;
  39.  
  40. function SoapMonitor: TSoapMonitor;
  41.  
  42. implementation
  43.  
  44. var
  45.   Monitor: TSoapMonitor;
  46.  
  47. type
  48.   TraceExtension = class(SoapExtension)
  49.   strict private
  50.     OldStream, NewStream: Stream;
  51.     class procedure CopyStream(Source, Dest: Stream);
  52.     function SoapContent: string;
  53.   public
  54.     function ChainStream(s: Stream): Stream; override;
  55.     function GetInitializer(serviceType: System.Type): System.Object; override;
  56.     function GetInitializer(methodInfo: LogicalMethodInfo; attribute: SoapExtensionAttribute): System.Object; override;
  57.     procedure Initialize(initializer: System.Object); override;
  58.     procedure ProcessMessage(message: SoapMessage); override;
  59.   end;
  60.  
  61. function SoapMonitor: TSoapMonitor;
  62. begin
  63.   if not Assigned(Monitor) then
  64.     Monitor := TSoapMonitor.Create;
  65.   Result := Monitor;
  66. end;
  67.  
  68. { TraceExtension }
  69.  
  70. function TraceExtension.ChainStream(s: Stream): Stream;
  71. begin
  72.   OldStream := s;
  73.   NewStream := MemoryStream.Create;
  74.   Result := NewStream;
  75. end;
  76.  
  77. class procedure TraceExtension.CopyStream(Source, Dest: Stream);
  78. var
  79.   Reader: TextReader;
  80.   Writer: TextWriter;
  81. begin
  82.   Reader := StreamReader.Create(Source);
  83.   Writer := StreamWriter.Create(Dest);
  84.   Writer.WriteLine(Reader.ReadToEnd);
  85.   Writer.Flush;
  86. end;
  87.  
  88. function TraceExtension.GetInitializer(serviceType: System.Type): System.Object;
  89. begin
  90.   Result := nil;
  91. end;
  92.  
  93. function TraceExtension.GetInitializer(methodInfo: LogicalMethodInfo; attribute: SoapExtensionAttribute): System.Object;
  94. begin
  95.   Result := nil;
  96. end;
  97.  
  98. procedure TraceExtension.Initialize(initializer: System.Object);
  99. begin
  100. end;
  101.  
  102. procedure TraceExtension.ProcessMessage(message: SoapMessage);
  103. begin
  104.   case message.Stage of
  105.     SoapMessageStage.AfterSerialize:
  106.       begin
  107.         Monitor.DoRequest(SoapContent);
  108.         CopyStream(NewStream, OldStream);
  109.       end;
  110.     SoapMessageStage.BeforeDeserialize:
  111.       begin
  112.         CopyStream(OldStream, NewStream);
  113.         Monitor.DoResponse(SoapContent);
  114.       end;
  115.   end;    
  116. end;
  117.  
  118. function TraceExtension.SoapContent: string;
  119. var
  120.   Reader: StreamReader;
  121. begin
  122.   NewStream.Position := 0;
  123.   Reader := StreamReader.Create(NewStream);
  124.   Result := Reader.ReadToEnd;
  125.   NewStream.Position := 0;
  126. end;
  127.  
  128. { TSoapMonitor }
  129.  
  130. procedure TSoapMonitor.DoRequest(const Xml: string);
  131. begin
  132.   if Assigned(FOnRequest) then
  133.     FOnRequest(Self, Xml);
  134. end;
  135.  
  136. procedure TSoapMonitor.DoResponse(const Xml: string);
  137. begin
  138.   if Assigned(FOnResponse) then
  139.     FOnResponse(Self, Xml);
  140. end;
  141.  
  142. class function TSoapMonitor.FormatXmlData(const Xml: string): string;
  143. var
  144.   Doc: XmlDocument;
  145.   Sw: StringWriter;
  146.   Xw: XmlTextWriter;
  147. begin
  148.   Doc := XmlDocument.Create;
  149.   Doc.LoadXml(Xml);
  150.   Sw := StringWriter.Create;
  151.   Xw := XmlTextWriter.Create(sw);
  152.   Xw.Formatting := Formatting.Indented;
  153.   Xw.Indentation := 2;
  154.   Xw.IndentChar := ' ';
  155.   doc.Save(xw);
  156.   Result := sw.ToString;
  157.   Xw.Close;
  158.   Sw.Close;
  159. end;
  160.  
  161. { TraceExtensionAttribute }
  162.  
  163. function TraceExtensionAttribute.get_ExtensionType: System.Type;
  164. begin
  165.   Result := typeof(TraceExtension);
  166. end;
  167.  
  168. function TraceExtensionAttribute.get_Priority: Integer;
  169. begin
  170.   Result := FPriority;
  171. end;
  172.  
  173. procedure TraceExtensionAttribute.set_Priority(value: Integer);
  174. begin
  175.   FPriority := value;
  176. end;
  177.  
  178. end.
  179.